#ifndef __LANE_CONTROL_H
#define __LANE_CONTROL_H

#include "laneLibuv.h"
#include "CxlUtil.h"
#include "minmea.h"
#include <arpa/inet.h>
#include <stddef.h>
#include <stdbool.h>

// 帧定义
#define HEAD_T                \
    uint16_t head;            \
    uint32_t station_no;      \
    uint8_t serial_no;        \
    uint8_t device_no[12];    \
    uint8_t head_reserve[12]; \
    uint8_t cmd;              \
    uint16_t len;

// 设备静态参数
#define DEVICE_ARG_T                   \
    uint8_t device_no_dup[12];         \
    uint8_t host_version[8];           \
    uint8_t misc1_version[8];          \
    uint8_t misc2_version[8];          \
    uint8_t host_hardware_version[8];  \
    uint8_t misc1_hardware_version[8]; \
    uint8_t misc2_hardware_version[8]; \
    uint8_t vz_version[8];

// 设备运行参数
#define DEVICE_RUNNING_ARG_T                 \
    uint8_t device_running_status;           \
    uint8_t device_running_direction;        \
    uint8_t device_running_speed;            \
    uint32_t device_running_location;        \
    uint16_t charge_voltage;                 \
    uint16_t battery_voltage;                \
    uint16_t battery_electric;               \
    uint16_t battery_temperature;            \
    uint8_t net_status;                      \
    uint8_t device_timeBcd[BCD_TIME_LENGTH]; \
    uint8_t device_reserve[8];

#define FILE_BLOCK_SIZE 2048
#define FILE_BLOCK_T                                                                                                  \
    uint16_t file_id;   /*文件代码, 每个文件对应一个ID, 一个文件的每个分包的文件ID都一样*/ \
    uint16_t block_num; /*文件分包总数*/                                                                        \
    uint16_t block_no;  /*文件分包序号*/                                                                        \
    uint16_t file_type; /*文件类别*/                                                                              \
    /* 以下6字节为特征定义 */                                                                                \
    uint16_t calculate_file_crc;           /*原文件的crc*/                                                        \
    uint16_t last_bytes;                   /*最后一个块的大小*/                                               \
    uint8_t pic_nums;                      /*图片序数*/                                                           \
    uint8_t cam_id;                        /*摄像机id*/                                                            \
    uint8_t pic_time_bcd[BCD_TIME_LENGTH]; /*同一个文件的所有传输包均相同YYMMDDHHmmSS*/                 \
    uint8_t body[FILE_BLOCK_SIZE];

// crc字段
#define CRC_T uint16_t crc;

// 帧头部
typedef struct
{
    HEAD_T
} __attribute__((__packed__)) head_t;

// 设备静态参数结构体
typedef struct
{
    DEVICE_ARG_T
} __attribute__((__packed__)) device_arg_t;

// 设备运行参数结构体
typedef struct
{
    DEVICE_RUNNING_ARG_T
} __attribute__((__packed__)) device_running_t;

/**************** 客户端发送帧 ****************/
// 注册帧
typedef struct
{
    HEAD_T
    DEVICE_ARG_T
    uint8_t encrypt_key[8];   // 密钥
    uint8_t register_version; // 版本号
    uint8_t register_reserve[7];
    CRC_T
} __attribute__((__packed__)) registration_t;

// 心跳帧
typedef struct
{
    HEAD_T
    uint8_t heartbeat_timeBcd[BCD_TIME_LENGTH];
    DEVICE_RUNNING_ARG_T
    uint8_t gps_gngga_data[MINMEA_MAX_LENGTH];
    uint8_t gps_gnrmc_data[MINMEA_MAX_LENGTH];
    CRC_T
} __attribute__((__packed__)) heart_beat_t;

// 霍尔传感器数据
typedef struct
{
    HEAD_T
    uint8_t hall_data_type;
    uint8_t hall_data;
    uint32_t hall_high_accuracy_time;
    CRC_T
} __attribute__((__packed__)) hall_t;

// 泛文件响应
typedef struct
{
    HEAD_T
    uint32_t file_block_response_code; // 返回码
    uint16_t file_block_file_code;     // 文件代码
    uint16_t file_block_type;          // 文件类别
    CRC_T
} __attribute__((__packed__)) file_block_send_t;

// 图片上传
typedef struct
{
    HEAD_T
    FILE_BLOCK_T
    CRC_T
} __attribute__((__packed__)) pic_block_send_t;

/**************** 服务端应答帧 ****************/
// 服务器注册应答帧
typedef struct
{
    HEAD_T
    uint8_t respon_registration_auth_status;
    uint8_t respon_registration_timeBcd[BCD_TIME_LENGTH];
    uint8_t respon_registration_encrypt_key[8]; // ZJLMZWCX
    CRC_T
} __attribute__((__packed__)) respon_registration_t;

// 服务器心跳应答帧
typedef struct
{
    HEAD_T
    uint8_t respon_heart_beat_timeBcd[BCD_TIME_LENGTH];
    int32_t respon_heart_beat_back_code;
    // int32_t respon_heart_beat_reserve;
    CRC_T
} __attribute__((__packed__)) respon_heart_beat_t;

// 霍尔传感器数据应答帧
typedef struct
{
    HEAD_T
    int32_t hall_back_code;
    CRC_T
} __attribute__((__packed__)) respon_hall_t;

// 图片上传后服务器的响应
typedef struct
{
    HEAD_T
    uint8_t pic_block_send_back_time_bcd[BCD_TIME_LENGTH];
    bool pic_block_send_back_pic_type;
    uint8_t pic_block_send_back_cam_id;
    uint8_t pic_block_send_back_file_no; // 图片序号
    CRC_T
} __attribute__((__packed__)) respon_pic_block_recv_t;

// 车位标定控制
typedef struct
{
    HEAD_T
    uint8_t calibration_control_cmd;
    CRC_T
} __attribute__((__packed__)) respon_calibration_t;

#define START_CALIBRATION_V2 0x01
#define STOP_CALIBRATION_V2 0x02
// 车位标定控制v2
typedef struct
{
    HEAD_T
    uint8_t calibration_control_cmd_v2;
    CRC_T
} __attribute__((__packed__)) respon_calibration_v2_t;

// 泛文件下发
typedef struct
{
    HEAD_T
    FILE_BLOCK_T
    CRC_T
} __attribute__((__packed__)) file_block_frame_t;

#define CAL_FRAME_DATA_LEN_TO_NET(type) htons(sizeof(type) - sizeof(head_t) - MEM_SIZE(type, crc))
#define CAL_FRAME_DATA_LEN(type) (sizeof(type) - sizeof(head_t) - MEM_SIZE(type, crc))

#define CRC_BASE_ADDR(type) offsetof(type, station_no)

// 对外函数
void laneAppInit();
void laneRegister();
void lane_uv_try_write(const uv_buf_t *bufs);
void lane_write_cb(uv_write_t *req, int32_t status);
void headInit(head_t *head, uint8_t cmd);
void laneHeardBeatTask(uv_timer_t *handle);
bool getIsConnectToServ();
void dispatchSendPendingQueue();

#endif
